Hi 大家,昨天我們學習了基本的函式和流程控制,今天我們來深入探討更進階的控制流程概念,包括迴圈的進階用法、錯誤處理的基礎,以及如何在實際專案中運用這些概念。這些在軟體開發中特別是在處理使用者輸入和系統穩定性方面十分重要。
fn main() {
// 巢狀迴圈與標籤控制
let mut count = 0;
'counting_up: loop {
println!("count = {}", count);
let mut remaining = 10;
loop {
println!("remaining = {}", remaining);
if remaining == 9 {
break; // 只跳出內層迴圈
}
if count == 2 {
break 'counting_up; // 跳出外層迴圈
}
remaining -= 1;
}
count += 1;
}
println!("結束計數,count = {}", count);
}
fn main() {
let numbers = vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// 過濾偶數並平方
let even_squares: Vec<i32> = numbers
.iter()
.filter(|&&x| x % 2 == 0)
.map(|&x| x * x)
.collect();
println!("偶數的平方: {:?}", even_squares);
// 使用 enumerate 取得索引
for (index, value) in numbers.iter().enumerate() {
if index % 2 == 0 {
println!("索引 {} 的值: {}", index, value);
}
}
// 範圍與步長
for i in (0..10).step_by(2) {
println!("步長為 2: {}", i);
}
}
fn main() {
let numbers = vec![1, 2, 3, 4, 5];
// 安全的陣列存取
match get_element(&numbers, 2) {
Some(value) => println!("找到值: {}", value),
None => println!("索引超出範圍"),
}
// 使用 if let 簡化
if let Some(value) = get_element(&numbers, 10) {
println!("找到值: {}", value);
} else {
println!("沒有找到值");
}
// 連鎖操作
let result = get_element(&numbers, 1)
.map(|x| x * 2)
.unwrap_or(0);
println!("處理後的結果: {}", result);
}
fn get_element(vec: &Vec<i32>, index: usize) -> Option<i32> {
if index < vec.len() {
Some(vec[index])
} else {
None
}
}
fn main() {
// 字串轉數字的錯誤處理
let inputs = ["42", "abc", "123", "xyz"];
for input in inputs {
match parse_number(input) {
Ok(number) => println!("解析成功: {} -> {}", input, number),
Err(error) => println!("解析失敗: {}", error),
}
}
// 使用 unwrap_or 提供預設值
let number1 = parse_number("123").unwrap_or(0);
let number2 = parse_number("abc").unwrap_or(0);
println!("數字1: {}, 數字2: {}", number1, number2);
}
fn parse_number(input: &str) -> Result<i32, String> {
match input.parse::<i32>() {
Ok(num) => Ok(num),
Err(_) => Err(format!("無法將 '{}' 轉換為數字", input)),
}
}
fn main() {
let point = (3, 5);
match point {
(0, 0) => println!("原點"),
(x, 0) => println!("在 X 軸上,x = {}", x),
(0, y) => println!("在 Y 軸上,y = {}", y),
(x, y) if x == y => println!("在對角線上: ({}, {})", x, y),
(x, y) => println!("其他位置: ({}, {})", x, y),
}
// 解構陣列
let array = [1, 2, 3, 4, 5];
match array {
[1, second, .., last] => {
println!("第一個是 1,第二個是 {},最後一個是 {}", second, last);
}
[first, .., last] => {
println!("第一個是 {},最後一個是 {}", first, last);
}
_ => println!("其他模式"),
}
}
use std::io;
#[derive(Debug, Clone)]
struct Student {
name: String,
scores: Vec<i32>,
}
#[derive(Debug)]
enum GradeLevel {
Excellent, // 90-100
Good, // 80-89
Average, // 70-79
NeedsImprovement, // 60-69
Failing, // 0-59
}
fn main() {
println!("=== 學生成績管理系統 ===");
let mut students = Vec::new();
loop {
println!("\n選擇操作:");
println!("1. 新增學生");
println!("2. 輸入成績");
println!("3. 查看成績報告");
println!("4. 離開");
let choice = get_user_choice();
match choice {
1 => add_student(&mut students),
2 => add_score(&mut students),
3 => show_report(&students),
4 => {
println!("謝謝使用!");
break;
}
_ => println!("無效選擇,請重新輸入"),
}
}
}
fn get_user_choice() -> i32 {
loop {
print!("請輸入選擇 (1-4): ");
let mut input = String::new();
match io::stdin().read_line(&mut input) {
Ok(_) => {
match input.trim().parse::<i32>() {
Ok(num) if num >= 1 && num <= 4 => return num,
_ => println!("請輸入 1 到 4 之間的數字"),
}
}
Err(_) => println!("讀取輸入時發生錯誤"),
}
}
}
fn add_student(students: &mut Vec<Student>) {
println!("請輸入學生姓名:");
let mut name = String::new();
match io::stdin().read_line(&mut name) {
Ok(_) => {
let name = name.trim().to_string();
if !name.is_empty() {
students.push(Student {
name: name.clone(),
scores: Vec::new(),
});
println!("已新增學生: {}", name);
} else {
println!("姓名不能為空");
}
}
Err(_) => println!("讀取姓名時發生錯誤"),
}
}
fn add_score(students: &mut Vec<Student>) {
if students.is_empty() {
println!("目前沒有學生,請先新增學生");
return;
}
// 顯示學生列表
println!("選擇學生:");
for (index, student) in students.iter().enumerate() {
println!("{}. {}", index + 1, student.name);
}
let student_index = loop {
println!("請輸入學生編號:");
let mut input = String::new();
match io::stdin().read_line(&mut input) {
Ok(_) => {
match input.trim().parse::<usize>() {
Ok(num) if num >= 1 && num <= students.len() => {
break num - 1;
}
_ => println!("請輸入有效的學生編號"),
}
}
Err(_) => println!("讀取輸入時發生錯誤"),
}
};
// 輸入成績
let score = loop {
println!("請輸入成績 (0-100):");
let mut input = String::new();
match io::stdin().read_line(&mut input) {
Ok(_) => {
match input.trim().parse::<i32>() {
Ok(num) if num >= 0 && num <= 100 => break num,
_ => println!("請輸入 0 到 100 之間的成績"),
}
}
Err(_) => println!("讀取成績時發生錯誤"),
}
};
students[student_index].scores.push(score);
println!("已為 {} 新增成績: {}", students[student_index].name, score);
}
fn show_report(students: &Vec<Student>) {
if students.is_empty() {
println!("目前沒有學生資料");
return;
}
println!("\n=== 成績報告 ===");
for student in students {
println!("\n學生: {}", student.name);
if student.scores.is_empty() {
println!(" 尚無成績記錄");
continue;
}
let average = calculate_average(&student.scores);
let grade_level = determine_grade_level(average);
println!(" 成績: {:?}", student.scores);
println!(" 平均: {:.1}", average);
println!(" 等級: {:?}", grade_level);
// 顯示成績統計
if let Some(highest) = student.scores.iter().max() {
println!(" 最高分: {}", highest);
}
if let Some(lowest) = student.scores.iter().min() {
println!(" 最低分: {}", lowest);
}
}
// 班級統計
show_class_statistics(students);
}
fn calculate_average(scores: &Vec<i32>) -> f64 {
if scores.is_empty() {
return 0.0;
}
let sum: i32 = scores.iter().sum();
sum as f64 / scores.len() as f64
}
fn determine_grade_level(average: f64) -> GradeLevel {
match average as i32 {
90..=100 => GradeLevel::Excellent,
80..=89 => GradeLevel::Good,
70..=79 => GradeLevel::Average,
60..=69 => GradeLevel::NeedsImprovement,
_ => GradeLevel::Failing,
}
}
fn show_class_statistics(students: &Vec<Student>) {
let students_with_scores: Vec<&Student> = students
.iter()
.filter(|student| !student.scores.is_empty())
.collect();
if students_with_scores.is_empty() {
return;
}
println!("\n=== 班級統計 ===");
let all_scores: Vec<i32> = students_with_scores
.iter()
.flat_map(|student| &student.scores)
.cloned()
.collect();
let class_average = calculate_average(&all_scores);
println!("班級平均: {:.1}", class_average);
// 等級分布
let mut grade_counts = [0; 5]; // [優秀, 良好, 普通, 需改進, 不及格]
for student in &students_with_scores {
let avg = calculate_average(&student.scores);
let grade_index = match determine_grade_level(avg) {
GradeLevel::Excellent => 0,
GradeLevel::Good => 1,
GradeLevel::Average => 2,
GradeLevel::NeedsImprovement => 3,
GradeLevel::Failing => 4,
};
grade_counts[grade_index] += 1;
}
let grade_names = ["優秀", "良好", "普通", "需改進", "不及格"];
println!("等級分布:");
for (i, &count) in grade_counts.iter().enumerate() {
if count > 0 {
println!(" {}: {} 人", grade_names[i], count);
}
}
}
今天我們學習了: